package com.dx.financehy.modules.security.rest;

import com.dx.financehy.annotation.Log;
import com.dx.financehy.annotation.rest.AnonymousGetMapping;
import com.dx.financehy.annotation.rest.AnonymousPostMapping;
import com.dx.financehy.config.security.MyUsernamePasswordAuthenticationToken;
import com.dx.financehy.exception.BadRequestException;
import com.dx.financehy.modules.security.config.bean.LoginProperties;
import com.dx.financehy.modules.security.config.bean.SecurityProperties;
import com.dx.financehy.modules.security.domain.dto.AuthUserDto;
import com.dx.financehy.modules.security.domain.dto.JwtUserDto;
import com.dx.financehy.modules.security.security.TokenProvider;
import com.dx.financehy.modules.security.service.OnlineUserService;
import com.dx.financehy.modules.security.service.TaskService;
import com.dx.financehy.modules.security.utils.LoginUtil;
import com.dx.financehy.modules.system.service.UserService;
import com.dx.financehy.utils.R;
import com.dx.financehy.utils.RedisUtils;
import com.dx.financehy.utils.enums.LoginMode;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author: huang_jigao
 * @Title: AuthorizationController
 * @ProjectName: financehy
 * @Description:
 * @date: 2023-12-05 8:56
 */

@Slf4j
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
@Api(tags = "系统：系统授权接口")
public class AuthorizationController {
    private final SecurityProperties properties;
    private final RedisUtils redisUtils;
    private final OnlineUserService onlineUserService;
    private final TokenProvider tokenProvider;
    private final AuthenticationManagerBuilder authenticationManagerBuilder;
    private final LoginProperties loginProperties;
    private final LoginUtil loginUtil;
    private final UserService userService;
    @Value("${spring.profiles.active}")
    private String active;
    @Autowired
    private TaskService taskService;

    @ApiOperationSupport(author = "itHuang")
    @Log("用户登录")
    @ApiOperation("登录授权")
    @AnonymousPostMapping(value = "/login")
    public R<Object> login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception {
        /*long expire = redisUtils.getExpire(loginUtil.loginFailedLockKey(authUser.getUsername()));
        if (expire > 0) {
            throw new BadRequestException("账号已被锁定");
        }*/
        // 密码解密
        String password = authUser.getPassword();

        log.info("解密了个啥：{}",password);
        Authentication authentication;
        try {
            MyUsernamePasswordAuthenticationToken authenticationToken
                    = new MyUsernamePasswordAuthenticationToken(authUser.getUsername(), password, LoginMode.PW);
            authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } catch (AuthenticationException e) {
            loginUtil.incrementCount(authUser.getUsername());
            log.error("账号或密码错误!", e);
            throw new BadRequestException("账号或密码错误");
        }
        // 生成令牌
        String token = tokenProvider.createToken(authentication);
        final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal();

        // 保存在线信息
        onlineUserService.save(jwtUserDto, token, request);
        jwtUserDto.getUser().setPassword(null);
        jwtUserDto.getUser().setEnabled(null);
        // 返回 token 与 用户信息
        Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
            put("token", properties.getTokenStartWith() + token);
            put("user", jwtUserDto);
        }};
        if (loginProperties.isSingleLogin()) {
            //踢掉之前已经登录的token
            onlineUserService.checkLoginOnUser(authUser.getUsername(), token);
        }
        return R.ok(authInfo);

    }

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation("测试testLogin")
    @AnonymousPostMapping(value = "/testLogin")
    public String login() throws Exception {
        String taskId = UUID.randomUUID().toString(); // 生成唯一任务ID
        taskService.startTask(taskId);
        return "Task started with ID: " + taskId;
    }

    @ApiOperationSupport(author = "itHuang")
    @ApiOperation("测试progress")
    @AnonymousGetMapping("/progress")
    public int getProgress(@RequestParam String taskId) {
        return taskService.getProgress(taskId);
    }
}
